import re,sys,os
import re
import glob
from PySide6.QtGui import *
from PySide6.QtWidgets import *
from PySide6.QtCore import *
import fitz  # PyMuPDF
from PIL import Image
import io
import pytesseract
import cv2
import numpy as np
# from pdf2image import convert_from_path
# from PIL import Image
# # 配置路径（根据你的系统修改）
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'  # Windows示例

def app_path():
    if hasattr(sys, 'frozen'):  
        return os.path.abspath(sys.executable)
    return os.path.abspath(__file__) 

class OpenFolderWidget(QWidget):
    def __init__(self, title: str):
        super().__init__()
        self.label = QLabel(title)
        self.edit = QLineEdit()
        self.button_open = QPushButton('open folder')
        self.layout = QHBoxLayout(self)
        self.layout.addWidget(self.label)
        self.layout.addWidget(self.edit)
        self.layout.addWidget(self.button_open)
        self.edit.setReadOnly(True)

class ProgressBarWidget(QWidget):
    def __init__(self, title: str):
        super().__init__()
        self.label = QLabel(title)
        self.button_start = QPushButton('start')
        self.progress_bar = QProgressBar()
        self.progress_bar.setValue(0)
        self.layout = QHBoxLayout(self)
        self.layout.addWidget(self.label)
        self.layout.addWidget(self.progress_bar)
        self.layout.addWidget(self.button_start)

class CodeCheckView(QWidget):
    signal_folder = Signal(str)
    signal_excelfile = Signal(str)
    signal_currentfile = Signal(str)
    def __init__(self):
        super().__init__()
        self.gtr_workbook_events = None
        self.code_path = OpenFolderWidget('File path:   ')
        self.progress = ProgressBarWidget('Progress bar:')
        input_layout = QVBoxLayout()
        input_layout.addWidget(self.code_path)
        input_layout.addWidget(self.progress)
        group_box_input = QGroupBox('')
        group_box_input.setLayout(input_layout)
        tab_layout = QVBoxLayout()
        tab_layout.addWidget(group_box_input)
        self.setLayout(tab_layout)
        self.setWindowTitle("compare pdf pages")
        self.resize(600, 200)
        self.show()

        self.code_path.button_open.clicked.connect(self.SlotChooseFolder)
        self.progress.button_start.clicked.connect(self.TraversalFolder)

    def ProgressBar(self, check_process): 
        self.progress.progress_bar.setValue(check_process)
        QCoreApplication.processEvents()

    def SlotChooseFolder(self): # open folder
        folder_path = QFileDialog.getExistingDirectory(self)
        self.code_path.edit.setText(folder_path)
        self.signal_folder = folder_path
    
    def SlotChooseExcelFile(self): # open excel
        file_path = QFileDialog.getOpenFileName(self)
        self.excel_path.edit.setText(file_path[0])
        self.signal_excelfile = file_path[0]

    def TraversalFolder(self): # start
        folder_path = self.signal_folder
        for filename in glob.glob(f'{folder_path}/**/*.pdf',recursive=True):
            print(filename)
            pdf_images_to_text(filename)
            self.ProgressBar((glob.glob(f'{folder_path}/**/*.pdf',recursive=True).index(filename)+1)/len(glob.glob(f'{folder_path}/**/*.pdf',recursive=True)) * 100)
        QMessageBox.information(None, 'result', 'PDF file add comments completed.           ')

def process_image(img, lang):
    """
    对图像进行预处理和OCR识别
    :param img: PIL Image对象
    :param lang: Tesseract语言包
    :return: 识别的文本
    """
    # 转换为灰度图像
    img_gray = img.convert('L')
    
    # 转换为numpy数组以便OpenCV处理
    img_np = np.array(img_gray)
    
    # 应用高斯模糊
    img_blur = cv2.GaussianBlur(img_np, (5, 5), 0)
    
    # 二值化处理
    _, img_bin = cv2.threshold(img_blur, 127, 255, cv2.THRESH_BINARY)
    
    # 去噪（使用中值滤波）
    img_clean = cv2.medianBlur(img_bin, 3)
    
    # 转换回PIL Image对象
    img_processed = Image.fromarray(img_clean)
    
    # 进行OCR识别
    text = pytesseract.image_to_string(img_processed, lang=lang)
    
    return text

def pdf_images_to_text(pdf_path, output_txt="output.txt", lang='jpn+eng', dpi=300):
    """
    使用PyMuPDF从PDF提取图片并识别文字，每页分左右两部分处理
    :param pdf_path: PDF文件路径
    :param output_txt: 输出文本文件
    :param lang: 语言组合
    :param dpi: 图像分辨率
    """
    try:
        full_text = []
        doc = fitz.open(pdf_path)
        
        for page_num in range(len(doc)):
            # 1. 将PDF页面转为图像
            page = doc.load_page(page_num)
            pix = page.get_pixmap(matrix=fitz.Matrix(dpi/72, dpi/72))  # 控制DPI
            img_bytes = pix.tobytes("ppm")  # 转换为PPM格式字节流
            
            # 2. 用PIL打开图像
            with Image.open(io.BytesIO(img_bytes)) as img:
                width, height = img.size
                
                # 3. 分割左右页面
                left_img = img.crop((0, 0, width // 2, height))
                right_img = img.crop((width // 2, 0, width, height))
                
                # 4. 处理左半部分
                left_text = process_image(left_img, lang)
                full_text.append(f"=== 第 {page_num+1} 页 左半部分 ===")
                full_text.append(left_text)
                
                # 5. 处理右半部分
                right_text = process_image(right_img, lang)
                full_text.append(f"=== 第 {page_num+1} 页 右半部分 ===")
                full_text.append(right_text)
                
                # 可选：保存处理后的图像
                left_img.save(f"page_{page_num+1}_left_processed.png")
                right_img.save(f"page_{page_num+1}_right_processed.png")
        
        # 6. 保存结果
        with open(output_txt, 'w', encoding='utf-8') as f:
            f.write('\n'.join(full_text))
        
        print(f"识别完成！结果已保存到 {output_txt}")
            
    except Exception as e:
        print(f"处理失败: {str(e)}")
    finally:
        doc.close()

# def pdf_images_to_text(pdf_path, output_txt="output.txt", lang='jpn+eng', dpi=300):
#     """
#     使用PyMuPDF从PDF提取图片并识别文字
#     :param pdf_path: PDF文件路径
#     :param output_txt: 输出文本文件
#     :param lang: 语言组合
#     :param dpi: 图像分辨率
#     """
#     try:
#         full_text = []
#         doc = fitz.open(pdf_path)
#         print(pytesseract.get_languages(config=''))
#         for page_num in range(len(doc)):
#             # 1. 将PDF页面转为图像
#             page = doc.load_page(page_num)
#             pix = page.get_pixmap(matrix=fitz.Matrix(dpi/72, dpi/72))  # 控制DPI
#             img_bytes = pix.tobytes("ppm")  # 转换为PPM格式字节流
            
#             # 2. 用PIL打开图像
#             with Image.open(io.BytesIO(img_bytes)) as img:
#                 # 3. 图像预处理
#                 img = img.convert('L')  # 灰度化
#                 img = img.point(lambda x: 0 if x < 140 else 255)  # 二值化
                
#                 # 4. OCR识别
#                 text = pytesseract.image_to_string(img, lang=lang)
#                 full_text.append(f"=== 第 {page_num+1} 页 ===")
#                 full_text.append(text)
                
#                 # 可选：保存处理后的图像
#                 img.save(f"page_{page_num+1}_processed.png")
        
#         # 5. 保存结果
#         with open(output_txt, 'w', encoding='utf-8') as f:
#             f.write('\n'.join(full_text))
        
#         print(f"识别完成！结果已保存到 {output_txt}")
            
#     except Exception as e:
#         print(f"处理失败: {str(e)}")
#     finally:
#         doc.close()


if __name__ == "__main__":
    # if os.path.exists(error_file):
    #     os.remove(error_file)
    # data = [["CPP file path", "Error description"]]
    # # print(f"{data}")
    # export_to_csv(data,error_file)

    app = QApplication([])
    window = CodeCheckView()
    app.exec()